#ifndef __MY_SINK__
#define __MY_SINK__
#include"util.hpp"
#include <memory>
#include <fstream>
#include<cassert>
namespace zylog{
    //基类
    class LogSink{
        public:
        using ptr=std::shared_ptr<LogSink>;
        LogSink(){}
        virtual ~LogSink(){}
        virtual void log(const char*data,size_t len)=0;
    };
    //落地方向：标准输出
    class StdoutSink:public LogSink{
        public:
        void log(const char*data,size_t len){
            std::cout.write(data,len);
        }
    };
    //落地方向：指定文件
    class FileSink:public LogSink{
        public:
        FileSink(const std::string &pathname):_pathname(pathname){
            //1.创建文件所在的目录
            util::File::createDirectory(util::File::path(pathname));
            //2.创建并打开日志文件
            _ofs.open(_pathname,std::ios::binary|std::ios::app);
            assert(_ofs.is_open());
        }
        void log(const char*data,size_t len){
            _ofs.write(data,len);
            assert(_ofs.good());
        }
        private:
        std::string _pathname;
        std::ofstream _ofs;
    };
    class RollBySizeSink:public LogSink{
        public:
            RollBySizeSink(const std::string &basename,size_t max_size):
            _basename(basename),_max_fsize(max_size),_cur_fsize(0),_name_count(0){
                std::string pathname=createNewFile();
                //1.创建文件所在目录
                util::File::createDirectory(util::File::path(pathname));
                //2.创建并打开文件
                _ofs.open(pathname,std::ios::binary|std::ios::app);
                assert(_ofs.is_open());
            }
            //将日志消息写入，写入前判断文件大小，超过最大大小就切换文件
            void log(const char*data,size_t len){
                if(_cur_fsize>=_max_fsize){
                    _ofs.close();
                    std::string pathname=createNewFile();
                    _ofs.open(pathname,std::ios::binary|std::ios::app);
                    assert(_ofs.is_open());
                    //这应该更新一下_cur_fsize
                    _cur_fsize=0;
                }
                _ofs.write(data,len);
                assert(_ofs.good());
                 
                 _cur_fsize+=len;
            }
        private:
        std::string createNewFile(){     
//获取系统时间，以时间来构造文件名扩展名
        time_t t= util::Date::now();
        struct tm lt;
        localtime_r(&t,&lt);
        std::stringstream filename;
        filename<<_basename;
        filename<< lt.tm_year+1900;
        filename<< lt.tm_mon+1;
        filename<< lt.tm_mday;
        filename << lt.tm_hour;
        filename << lt.tm_min;
        filename << lt.tm_sec;
        filename<<"-";
        filename<<_name_count++;
        filename<<".log";
        return filename.str();
        }
        private:
        size_t _name_count;
        std::string _basename;
        std::ofstream _ofs;
        size_t _max_fsize;
        size_t _cur_fsize;
};

    class SinkFactory{
        public:
            template<typename SinkType,typename ...Args>
            static LogSink::ptr create(Args&&...args){
                return std::make_shared<SinkType>(std::forward<Args>(args)...);
            }
    };
}
#endif